﻿using System;
using System.Collections.Generic;
using System.Transactions;
using Bingosoft.Data;
using Bingosoft.Modules.SecurityConsole.Common.Helper;

namespace Bingosoft.Modules.SecurityConsole.Role
{
    public class RoleService
    {
        private readonly Dao dao = Dao.Get();

        /// <summary>
        /// 获取单条角色信息
        /// </summary>
        /// <param name="roleId">角色ID</param>
        public RoleInfo GetRoleById(string roleId)
        {
            RoleInfo roleInfo;
            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Suppress))
            {
                IDictionary<string, object> dictionary = new Dictionary<string, object> { { "Id", roleId } };
                roleInfo = dao.QueryEntity<RoleInfo>("role.get.role.by.Id", dictionary);
                transactionScope.Complete();
            }
            return roleInfo;
        }

        /// <summary>
        /// 更新角色信息
        /// </summary>
        /// <param name="roleInfo">角色信息</param>
        public void SaveOrUpdate(RoleInfo roleInfo)
        {
            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required))
            {
                dao.ExecuteNonQuery(string.IsNullOrEmpty(roleInfo.Id) ? "role.insertRoleInfo" : "role.updateRoleInfo",
                                            roleInfo);
                transactionScope.Complete();
            }
        }

        /// <summary>
        /// 删除单条角色
        /// </summary>
        /// <param name="roleId">角色Id</param>
        public void DeleteRole(string roleId)
        {
            DeleteRoles(new string[] { roleId });
        }

        /// <summary>
        /// 批量删除角色
        /// </summary>
        /// <param name="roleIds">角色Id的数组</param>
        public void DeleteRoles(string[] roleIds)
        {
            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required))
            {
                IDictionary<string, object> dictionary = new Dictionary<string, object>();
                foreach (string roleId in roleIds)
                {
                    dictionary["RoleId"] = roleId;
                    dao.ExecuteNonQuery("role.deleteUserRoleByRoleId", dictionary);
                    dao.ExecuteNonQuery("role.deleteRolePermission", dictionary);
                    dao.ExecuteNonQuery("role.delete.role", dictionary);
                }
                transactionScope.Complete();
            }
        }

        /// <summary>
        /// 为特定角色批量删除用户
        /// </summary>
        /// <param name="roleId">角色Id</param>
        /// <param name="userIdList">用户Id数组</param>
        public void DeleleUserRoles(string roleId, string[] userIdList)
        {
            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required))
            {
                IDictionary<string, object> dictionary = new Dictionary<string, object> { { "RoleId", roleId } };
                foreach (string userId in userIdList)
                {
                    if (!string.IsNullOrEmpty(userId))
                    {
                        dictionary["UserId"] = userId;
                        dao.ExecuteNonQuery("role.deleteUserRole", dictionary);
                    }
                }
                transactionScope.Complete();
            }
        }

        /// <summary>
        /// 为特定角色批量添加用户
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="userIds"></param>
        public void AddUserRoles(string roleId, string userIds)
        {
            string[] userIdList = userIds.Split(',');
            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required))
            {
                IDictionary<string, object> dictionary = new Dictionary<string, object> { { "RoleId", roleId } };
                foreach (string userId in userIdList)
                {
                    dictionary["UserId"] = userId;
                    dao.ExecuteNonQuery("role.insertUserRole", dictionary);
                }
                transactionScope.Complete();
            }
        }

        /// <summary>
        /// 获取角色具备的对应的权限规则列表
        /// </summary>
        /// <param name="roleId">角色Id</param>
        /// <returns></returns>
        public IList<IDictionary<string, object>> GetSelectedOperationDataRulePrivilegeList(string roleId)
        {
            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Suppress))
            {
                IDictionary<string, object> dictionary = new Dictionary<string, object> { { "RoleId", roleId } };
                IList<IDictionary<string, object>> ruleList = dao.QueryDictionaries("role.privielgeAssign.getSelectedOperationRuleList", dictionary);
                transactionScope.Complete();
                return ruleList;
            }
        }

        /// <summary>
        /// 插入角色权限
        /// </summary>
        /// <param name="roleId">角色Id</param>
        /// <param name="operation">操作Id</param>
        /// <param name="ruleId">规则Id</param>
        private void InsertRolePermission(string roleId, string operation, string ruleId)
        {
            IDictionary<string, object> dictionary = new Dictionary<string, object> { { "RoleId", roleId }, { "Operation", operation } };
            if (string.IsNullOrEmpty(ruleId))
            {
                dictionary["RuleId"] = DBNull.Value;
            }
            else
            {
                dictionary["RuleId"] = ruleId;
            }

            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required))
            {
                dao.ExecuteNonQuery("role.privilegeAssign.insertRolePermission", dictionary);
                transactionScope.Complete();
            }
        }

        /// <summary>
        /// 更新角色对应的权限和权限规则
        /// </summary>
        /// <param name="roleId">角色Id</param>
        /// <param name="operation">操作Id</param>
        /// <param name="ruleId">规则Id</param>
        private void UpdateRolePermission(string roleId, string operation, string ruleId)
        {
            IDictionary<string, object> dictionary = new Dictionary<string, object>
                                                         {
                                                             {"RoleId", roleId},
                                                             {"Operation", operation},
                                                             {"RuleId", ruleId}
                                                         };
            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required))
            {
                dao.ExecuteNonQuery("role.privilegeAssign.updateRolePermission", dictionary);
                transactionScope.Complete();
            }
        }

        /// <summary>
        /// 删除角色对应的权限
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="operation"></param>
        private void DeleteRolePermission(string roleId, string operation)
        {
            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required))
            {
                IDictionary<string, object> dictionary = new Dictionary<string, object>
                                                         {
                                                             {"RoleId", roleId},
                                                             {"Operation", operation}
                                                         };
                dao.ExecuteNonQuery("role.privilegeAssign.deleteRolePermission", dictionary);
                transactionScope.Complete();
            }
        }

        /// <summary>
        /// 给角色批量赋权限
        /// </summary>
        /// <param name="privilegeList">权限ID数组</param>
        /// <param name="roleId">角色Id</param>
        public void SavePrivilege(string[] privilegeList, string roleId)
        {
            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required))
            {
                IList<IDictionary<string, object>> selectedOperationRuleList = GetSelectedOperationDataRulePrivilegeList(roleId);
                IDictionary<string, object> selectedOperationRuleDictionary = new Dictionary<string, object>();

                //将已选的操作和规则放入Dictionary进行缓存以便后面查询
                foreach (IDictionary<string, object> item in selectedOperationRuleList)
                {
                    string operation = DictionaryHelper.GetParamString(item, "Operation");
                    string ruleId = DictionaryHelper.GetParamString(item, "RuleId");
                    selectedOperationRuleDictionary.Add(operation, ruleId);
                }

                //将前台选择的项整理成Map方式以便后面查询
                IDictionary<string, object> operationRuleDictionary = new Dictionary<string, object>();
                foreach (string item in privilegeList)
                {
                    if (!String.IsNullOrEmpty(item))
                    {
                        string[] privilegeArray = item.Split(':');
                        string operation = privilegeArray[0];
                        string ruleId = privilegeArray[1];
                        operationRuleDictionary.Add(operation, ruleId);
                    }
                }

                //找出需要新增和更新的权限
                foreach (string item in privilegeList)
                {
                    if (String.IsNullOrEmpty(item)) continue;

                    string[] privilegeArray = item.Split(':');
                    string operation = privilegeArray[0];
                    string ruleId = privilegeArray[1];

                    if (selectedOperationRuleDictionary.ContainsKey(operation))
                    {
                        string operationRule = DictionaryHelper.GetParamString(selectedOperationRuleDictionary, operation);

                        if (string.IsNullOrEmpty(ruleId))
                        {
                            if (!string.IsNullOrEmpty(operationRule))
                            {
                                //更新RULEID -》由空白变成最新的值
                                UpdateRolePermission(roleId, operation, null);
                            }
                        }
                        else
                        {
                            if (!string.IsNullOrEmpty(operationRule))
                            {
                                if (!ruleId.Equals(operationRule))
                                {
                                    //更新RULEID-》由已有值更新为最新值
                                    UpdateRolePermission(roleId, operation, ruleId);
                                }
                            }
                            else
                            {
                                //更新RULEID -》清空
                                UpdateRolePermission(roleId, operation, ruleId);
                            }
                        }
                    }
                    else
                    {
                        InsertRolePermission(roleId, operation, ruleId);
                    }
                }

                //找出需要删除的权限
                foreach (IDictionary<string, object> item in selectedOperationRuleList)
                {
                    string operation = DictionaryHelper.GetParamString(item, "Operation");
                    if (!operationRuleDictionary.ContainsKey(operation))
                    {
                        //删除操作
                        DeleteRolePermission(roleId, operation);
                    }
                }
                transactionScope.Complete();
            }
        }

        /// <summary>
        /// 获取权限的所有规则列表
        /// </summary>
        /// <param name="operation">权限Id</param>
        /// <returns></returns>
        public IList<IDictionary<string, object>> GetOperationDataRulePrivilegeList(string operation)
        {
            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Suppress))
            {
                IDictionary<string, object> dictionary = new Dictionary<string, object> { { "Operation", operation } };
                IList<IDictionary<string, object>> ruleList = dao.QueryDictionaries("role.privilegeAssign.getOperationRuleList", dictionary);
                transactionScope.Complete();
                return ruleList;
            }
        }


        /// <summary>
        /// 批量增加继承的角色
        /// </summary>
        /// <param name="childId">角色Id</param>
        /// <param name="parentIds">父角色Id集合</param>
        /// <returns></returns>
        public Boolean AddRolesForInherit(string childId, string[] parentIds)
        {
            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required))
            {
                foreach (String roleId in parentIds)
                {
                    if (!string.IsNullOrEmpty(roleId))
                    {
                        IDictionary<string, object> parameters = new Dictionary<string, object> { { "childId", childId }, { "parentId", roleId } };
                        dao.ExecuteNonQuery("insert.role.inherit", parameters);
                    }
                }
                transactionScope.Complete();
                return true;
            }
        }

        /// <summary>
        /// 批量删除角色继承
        /// </summary>
        /// <param name="childRoleId">角色Id</param>
        /// <param name="parentRoleIds">父角色Id集合</param>
        /// <returns></returns>
        public Boolean DeleteRolesInherit(string childRoleId, string[] parentRoleIds)
        {
            if (null == parentRoleIds || parentRoleIds.Length == 0 || string.IsNullOrEmpty(childRoleId))
            {
                return false;
            }

            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required))
            {
                foreach (string roleId in parentRoleIds)
                {
                    IDictionary<string, object> parameters = new Dictionary<string, object>
                                                                 {
                                                                     {"childRoleId", childRoleId},
                                                                     {"parentRoleId",roleId}
                                                                 };
                    dao.ExecuteNonQuery("delete.role.inherit", parameters);
                }
                transactionScope.Complete();
                return true;
            }
        }
    }
}
